package com.zyj.java1;

/**
 * @program: JVMDemo
 * @ClassName StringIntern
 * @author: YaJun
 * @Date: 2021 - 12 - 29 - 11:01
 * @Package: com.zyj.java1
 * @Description:
 * 如果保证变量 s 指向的是字符串常量池中的数据呢？
 * 有两种方式：
 *  方式一：String s = "hello"; // 字面量定义的方式
 *  方式二：调用 intern() 方法
 *         String s = new String("hello").intern();
 *         String s = new StringBuilder("hello").toString().intern();
 */
public class StringIntern {

    public static void main(String[] args) {
//        String s = "hello".intern();
//        String s1 = new String("hello").intern();

        String s = new String("1"); // 造了两个对象：new String("1") 和 常量池中的 "1"
        s.intern(); // 调用此方法之前，字符串常量池中已经存在了 "1"
        String s2 = "1";
        System.out.println(s == s2);    // jdk6: false      jdk7/8：false

        String s3 = new String("1") + new String("1");  // s3变量记录的地址为：new String("11")，存于堆中
        // 执行完上一行代码以后，字符串常量池中是否存在 "11" 呢？答案：不存在！
        s3.intern();    // 在字符串常量池中生成 "11"  如何理解：   JDK6:创建了一个新的对象 "11"，也就有了新的地址
        //                                                      JDK7/8:此时常量中并没有创建 "11"，而是创建了一个指向堆空间中 new String("11") 的地址
        String s4 = "11";   // s4变量记录的地址：使用的是上一行代码执行时，在常量池中生成的 "11" 的地址
        System.out.println(s3 == s4);   // jdk6: false      jdk7/8：true
        // 如果将 第30行与31行互换，则答案为false
    }

}
